System.Drawing var input = File.ReadAllLines(Path.Combine(Path.GetDirectoryName(Util.CurrentQueryPath), "..", "day18.txt")); var instructions = input.Select(i => i.Split()).Select(i => new { op = i[0], reg = i[1], parm = i.Length > 2 ? i[2] : "" }).ToArray(); var registers = instructions.Select(i => i.reg).Where(i => !int.TryParse(i, out int ii)).Distinct().ToDictionary(i => i, i => 0L); long get(Dictionary regs, string x) => long.TryParse(x, out long y) ? y : regs[x]; bool doInst(Dictionary regs, ref long ins, Func rcv, Action snd, out long? ret) { ret = null; if (ins < -1 || ins >= instructions.Length) return false; var reg = instructions[ins].reg; switch (instructions[ins].op) { case "snd": snd(get(regs, reg)); break; case "set": regs[reg] = get(regs, instructions[ins].parm); break; case "add": regs[reg] += get(regs, instructions[ins].parm); break; case "mul": regs[reg] *= get(regs, instructions[ins].parm); break; case "mod": regs[reg] %= get(regs, instructions[ins].parm); break; case "rcv": ret = rcv(); if (ret == null) return false; regs[reg] = ret.Value; break; case "jgz": if (get(regs, reg) > 0) { ins += get(regs, instructions[ins].parm); ins--; } break; } ins++; return true; } var pos = 0L; long? part1 = null, lastSound = null; while (part1 == null) { if (!doInst(registers, ref pos, () => get(registers, instructions[pos].reg) != 0 ? lastSound : null, sound => lastSound = sound, out part1)) pos++; } part1.Dump(); long pos1 = 0, pos2 = 0; var q1 = new Queue(); var q2 = new Queue(); var regs1 = registers.ToDictionary(r => r.Key, r => 0L); var regs2 = registers.ToDictionary(r => r.Key, r => 0L); regs2["p"] = 1; var part2 = 0; while ((doInst(regs1, ref pos1, () => q1.Count > 0 ? (long?)q1.Dequeue() : null, snd => q2.Enqueue(snd), out long? x) | doInst(regs2, ref pos2, () => q2.Count > 0 ? (long?)q2.Dequeue() : null, snd => { q1.Enqueue(snd); part2++; }, out long? y))) { } part2.Dump();